#include <iostream>
#include <string>
#include <memory>

// 利用建造者模式来创建一个电脑。
// 好初始化。
class Computer
{
public:
    void SetBoard(const std::string& board)
    {
        _board = board;
    }
    void SetDisplay(const std::string& display)
    {
        _display = display;
    }
    // 主板和显示器都可以混用各个品牌的零件，但是操作系统只有一个。
    virtual void SetOs() = 0;
    void showcomputer()
    {
        std::string compose;
        compose += "Computer be made of:\n";
        compose += "\t" + _board + "\n";
        compose += "\t" + _display + "\n";
        compose += "\t" + _os + "\n";

        std::cout << compose << std::endl;
    }
protected:
    // 主板+屏幕+操作系统
    std::string _board;
    std::string _display;
    std::string _os;
};
class MacBook : public Computer
{
public:
    void SetOs() override
    {
        Computer::_os = "Macos x12";
    }
private:
    ;
};
class Builder
{
public:
    virtual void BuildBoard(const std::string& Board) = 0;
    virtual void BuildDisplay(const std::string& Display) = 0;
    virtual void BuildOs() = 0;
    virtual std::shared_ptr<Computer> Build() = 0;
};
class MacBuilder : public Builder
{
public:
    MacBuilder()
        :_computer(std::make_shared<MacBook>())
    {}
    void BuildBoard(const std::string& Board) override
    {
        _computer->SetBoard(Board);
    }
    void BuildDisplay(const std::string& Display) override
    {
        _computer->SetDisplay(Display);
    }
    void BuildOs() override
    {
        _computer->SetOs();
    }
    std::shared_ptr<Computer> Build() override
    {
        return _computer;
    }
private:
    std::shared_ptr<Computer> _computer;
};
class Director
{
public:
    Director(Builder* builder)
        :_builder(builder)
    {;}
    void Construct(const std::string& board,const std::string& display)
    {
        _builder->BuildBoard(board);
        _builder->BuildDisplay(display);
        _builder->BuildOs();
    }
private:
    std::shared_ptr<Builder> _builder;
};

int main()
{
    Builder* macbuild = new MacBuilder();
    Director director(macbuild);
    director.Construct("华为","联想");
    std::shared_ptr<Computer> computer = macbuild->Build();
    computer->showcomputer();

    return 0;
}